package com.atom.module.face.ui

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.SurfaceTexture
import android.hardware.SensorManager
import android.net.Uri
import android.os.*
import android.util.Log
import android.view.*
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.atom.module.face.R
import com.atom.module.face.encoder.EncoderBus
import com.atom.module.face.extensions.*
import com.atom.module.face.utils.SensorEventUtil
import com.atom.module.face.CameraShower
import com.atom.module.face.view.FaceView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import com.atom.module.face.bean.Permission
import com.atom.module.face.view.AutoTextureView
import com.atom.module.face.view.FocusView
import com.tenginekit.AndroidConfig
import com.tenginekit.KitCore
import com.tenginekit.face.Face
import com.tenginekit.model.TenginekitPoint
import java.util.*

class CameraActivity : AppCompatActivity() {
    companion object {
        const val AUTO_IMAGE_CAPTURE = "AUTO_IMAGE_CAPTURE"
        const val AUTO_IMAGE_FACE = "AUTO_IMAGE_FACE"

        const val TYPE_FACE_RECT = "TYPE_FACE_RECT"
        const val TYPE_FACE_LANDMARK_2D = "TYPE_FACE_LANDMARK_2D"

        const val AUTO_IMAGE_TIME = "AUTO_IMAGE_TIME"

        const val ACTION_VIDEO = "ACTION_VIDEO"
        const val ACTION_IMAGE = "ACTION_IMAGE"

        const val EXTRA_OUTPUT = "Extra_OUTPUT"

        const val STATE_SINGLE = "STATE_SINGLE"
    }

    private val FADE_DELAY = 5000L
    private val CAPTURE_ANIMATION_DURATION = 100L

    private val permissio = Permission()


    private lateinit var mOrientationEventListener: OrientationEventListener


    private var mPreview: CameraShower? = null
    private var mPreviewUri: Uri? = null
    private var mIsInPhotoMode = false
    private var mIsCameraAvailable = false
    private var mIsHardwareShutterHandled = false
    var mLastHandledOrientation = 0

    private var workHandler: Handler? = null
    private var workHandlerThread: HandlerThread? = null
    private var mTimerHandler: Handler = Handler(Looper.getMainLooper())
    private var mFadeHandler: Handler = Handler(Looper.getMainLooper())
    private var autoCaptureHandler: Handler = Handler(Looper.getMainLooper())

    private var sensorEventUtil: SensorEventUtil? = null
    private var isProcessingFrame = false

    @Volatile
    private var isFaceShow = false

    private val autoCaptureImage = Runnable {
        if (mIsInPhotoMode) {
            shutterPressed()
        }
    }

    @SuppressLint("MissingSuperCall")
    override fun onCreate(savedInstanceState: Bundle?) {
        window.addFlags(
            WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
                WindowManager.LayoutParams.FLAG_FULLSCREEN
        )
        super.onCreate(savedInstanceState)
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        setContentView(R.layout.activity_camera_face)
        initView()
        initVariables()
        tryInitCamera()
        supportActionBar?.hide()
        setupOrientationEventListener()
    }

    var auto_texture_view = lazy {
        findViewById<AutoTextureView>(R.id.auto_texture_view)
    }
    var view_holder = lazy {
        findViewById<RelativeLayout>(R.id.view_holder)
    }
    var capture_black_screen = lazy {
        findViewById<ImageView>(R.id.capture_black_screen)
    }
    var facing_overlay = lazy {
        findViewById<FaceView>(R.id.facing_overlay)
    }
    var focus_view = lazy {
        findViewById<FocusView>(R.id.focus_view)
    }
    var settings = lazy {
        findViewById<ImageView>(R.id.settings)
    }
    var toggle_photo_video = lazy {
        findViewById<ImageView>(R.id.toggle_photo_video)
    }
    var change_resolution = lazy {
        findViewById<ImageView>(R.id.change_resolution)
    }
    var last_photo_video_preview = lazy {
        findViewById<ImageView>(R.id.last_photo_video_preview)
    }
    var toggle_camera = lazy {
        findViewById<ImageView>(R.id.toggle_camera)
    }
    var shutter = lazy {
        findViewById<ImageView>(R.id.shutter)
    }
    var toggle_flash = lazy {
        findViewById<ImageView>(R.id.toggle_flash)
    }
    var video_rec_curr_timer = lazy {
        findViewById<TextView>(R.id.video_rec_curr_timer)
    }
    var btn_holder = lazy {
        findViewById<LinearLayout>(R.id.btn_holder)
    }

    private fun initView() {
        auto_texture_view.value

    }

    override fun onResume() {
        super.onResume()
        // init handler
        workHandlerThread = HandlerThread("inference").also {
            it.start()
            workHandler = Handler(it.looper)
        }
        if (hasStorageAndCameraPermissions()) {
            mPreview?.onResumed(auto_texture_view.value)
            resumeCameraItems()
            setupPreviewImage()
            scheduleFadeOut()
            focus_view.value.setStrokeColor(appConfig.primaryColor)
            toggleBottomButtons(false)
        }
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        if (hasStorageAndCameraPermissions()) {
            mOrientationEventListener.enable()
        }
    }

    override fun onPause() {
        try {
            workHandlerThread?.quitSafely()
            workHandlerThread?.join()
            workHandlerThread = null
            workHandler = null
        } catch (e: InterruptedException) {

        }
        super.onPause()
        window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        if (!hasStorageAndCameraPermissions()) {
            return
        }
        mFadeHandler.removeCallbacksAndMessages(null)
        hideTimer()
        mOrientationEventListener.disable()
        if (mPreview?.getCameraState() == STATE_PICTURE_TAKEN) {
            toast(R.string.photo_not_saved)
        }
        runOnWorkTHread {
            mPreview?.onPaused()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mPreview = null
        KitCore.release()
    }

    private fun initVariables() {
        mIsInPhotoMode = appConfig.initPhotoMode
        mIsCameraAvailable = false
        mIsHardwareShutterHandled = false
        mLastHandledOrientation = 0
        if (appConfig.alwaysOpenBackCamera) {
            appConfig.lastUsedCamera = backCameraId.toString()
        }
        if (isImageCaptureIntent()) {
            mIsInPhotoMode = true
        } else if (isVideoCaptureIntent()) {
            mIsInPhotoMode = false
        }
        mPreview = CameraShower(this, mIsInPhotoMode, isAutoCaptureImageByFace())
    }

    private fun tryInitCamera() {
        permissio.handlePermission(this, PERMISSION_CAMERA) { camera ->
            if (camera) {
                permissio.handlePermission(this, PERMISSION_WRITE_STORAGE) { storage ->
                    if (storage) {
                        initializeCamera()
                    } else {
                        toast(R.string.no_storage_permissions)
                        finish()
                    }
                }
            } else {
                toast(R.string.no_camera_permissions)
                finish()
            }
        }
    }

    private fun checkImageCaptureIntent() {
        if (isImageCaptureIntent() || isVideoCaptureIntent()) {
            val output = intent.extras?.get(EXTRA_OUTPUT)
            if (output != null && output is Uri) {
                mPreview?.setTargetUri(output)
            }
        }
    }

    private fun initializeCamera() {
        initButtons()

        findViewById<AutoTextureView>(R.id.auto_texture_view).surfaceTextureListener =
            object : TextureView.SurfaceTextureListener {
                override fun onSurfaceTextureSizeChanged(
                    surface: SurfaceTexture,
                    width: Int,
                    height: Int
                ) {
                    Log.e(
                        "CameraActivity",
                        "Activity -> onSurfaceTextureSizeChanged  $width  $height"
                    )
                    mPreview?.closeCamera()
                    mPreview?.setSurfaceAvailable(surface, width, height)
                }

                override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
                }

                override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean = true

                override fun onSurfaceTextureAvailable(
                    surface: SurfaceTexture,
                    width: Int,
                    height: Int
                ) {
                    Log.e(
                        "CameraActivity",
                        "Activity -> onSurfaceTextureAvailable  $width  $height"
                    )
                    mPreview?.setSurfaceAvailable(surface, width, height)
                }
            }
        checkImageCaptureIntent()

        val imageDrawable =
            if (appConfig.lastUsedCamera == backCameraId.toString()) R.drawable.ic_camera_front_vector else R.drawable.ic_camera_rear_vector

        findViewById<ImageView>(R.id.toggle_camera).setImageResource(imageDrawable)

        setupPreviewImage()

        val initialFlashlightState =
            if (appConfig.turnFlashOffAtStartup) FLASH_OFF else appConfig.flashlightState
        mPreview?.setFlashlightState(initialFlashlightState)
        updateFlashlightState(initialFlashlightState)
    }

    private fun initButtons() {
        // 前后置切换
        toggle_camera.value.setOnClickListener {
            if (checkCameraAvailable()) {
                mPreview?.toggleFrontBackCamera()
            }
        }
        // 照片预览
        last_photo_video_preview.value.setOnClickListener {
            // TODO 进行预览照片
            if (mPreviewUri != null) {
                Intent(this, PreviewActivity::class.java).apply {
                    this.data = mPreviewUri
                    startActivity(this)
                }
            }
        }
        // 闪关灯
        toggle_flash.value.setOnClickListener {
            if (checkCameraAvailable()) {
                mPreview?.toggleFlashlight()
            }
        }
        // 快门或者录像
        shutter.value.setOnClickListener { shutterPressed() }
        // 设置
        settings.value.setOnClickListener {
            if (settings.value.alpha == 1f) {
                val intent = Intent(applicationContext, SetActivity::class.java)
                startActivity(intent)
            } else {
                fadeInButtons()
            }
        }
        // 录像和拍照切换
        toggle_photo_video.value.setOnClickListener {
            permissio.handlePermission(this, PERMISSION_RECORD_AUDIO) {
                if (it) {
                    togglePhotoVideo()
                } else {
                    toast(R.string.no_audio_permissions)
                }
            }
        }
        // 分辨率大小配置
        change_resolution.value.setOnClickListener { mPreview?.showChangeResolutionDialog() }

        if (mIsInPhotoMode) {
            shutter.value.setImageResource(R.drawable.ic_shutter_vector)
        } else {
            shutter.value.setImageResource(R.drawable.ic_video_rec)
        }

        // 设置对焦
        focus_view.value.setOnTouchListener(mPreview)

    }


    fun updateFlashlightState(state: Int) {
        appConfig.flashlightState = state
        val flashDrawable = when (state) {
            FLASH_OFF -> R.drawable.ic_flash_off_vector
            FLASH_ON -> R.drawable.ic_flash_on_vector
            else -> R.drawable.ic_flash_auto_vector
        }
        toggle_flash.value.setImageResource(flashDrawable)
    }

    fun updateCameraIcon(isUsingFrontCamera: Boolean) {
        toggle_camera.value.setImageResource(if (isUsingFrontCamera) R.drawable.ic_camera_rear_vector else R.drawable.ic_camera_front_vector)
    }

    private fun shutterPressed() {
        if (checkCameraAvailable()) {
            handleShutter()
        }
    }

    private fun handleShutter() {
        if (mIsInPhotoMode) {
            toggleBottomButtons(true)
            mPreview?.tryTakePicture()
            capture_black_screen.value.animate().alpha(0.8f).setDuration(CAPTURE_ANIMATION_DURATION)
                .withEndAction {
                    capture_black_screen.value.animate().alpha(0f).setDuration(CAPTURE_ANIMATION_DURATION)
                        .start()
                }.start()
        } else {
            permissio.handlePermission(this, PERMISSION_RECORD_AUDIO) {
                if (it) {
                    mPreview?.toggleRecording()
                } else {
                    toast(R.string.no_audio_permissions)
                }
            }
        }
    }

    fun toggleBottomButtons(hide: Boolean) {
        runOnUiThread {
            val alpha = if (hide) 0f else 1f
            shutter.value.animate().alpha(alpha).start()
            toggle_camera.value.animate().alpha(alpha).start()
            toggle_flash.value.animate().alpha(alpha).start()

            shutter.value.isClickable = !hide
            toggle_camera.value.isClickable = !hide
            toggle_flash.value.isClickable = !hide
        }
    }

    private fun togglePhotoVideo() {
        if (!checkCameraAvailable()) {
            return
        }
        mPreview?.setFlashlightState(FLASH_OFF)
        hideTimer()
        mIsInPhotoMode = !mIsInPhotoMode
        appConfig.initPhotoMode = mIsInPhotoMode
        showToggleCameraIfNeeded()
        if (mIsInPhotoMode) {
            initPhotoMode()
        } else {
            tryInitVideoMode()
        }
        toggleBottomButtons(false)
    }

    private fun initPhotoMode() {
        toggle_photo_video.value.setImageResource(R.drawable.ic_video_vector)
        shutter.value.setImageResource(R.drawable.ic_shutter_vector)
        mPreview?.initPhotoMode()
        setupPreviewImage()
    }

    private fun tryInitVideoMode() {
        if (mPreview?.initVideoMode() == true) {
            initVideoButtons()
        } else {
            toast(R.string.video_mode_error)
        }
    }

    private fun initVideoButtons() {
        toggle_photo_video.value.setImageResource(R.drawable.ic_camera_vector)
        showToggleCameraIfNeeded()
        shutter.value.setImageResource(R.drawable.ic_video_rec)
        mPreview?.checkFlashlight()
    }

    private fun setupPreviewImage() {
        if (mPreviewUri == null) return
        runOnUiThread {
            if (!isDestroyed) {
                val options = RequestOptions()
                    .centerCrop()
                    .diskCacheStrategy(DiskCacheStrategy.NONE)

                Glide.with(this@CameraActivity)
                    .load(mPreviewUri)
                    .apply(options)
                    .transition(DrawableTransitionOptions.withCrossFade())
                    .into(last_photo_video_preview.value)
            }
        }
    }

    private fun scheduleFadeOut() {
        if (!appConfig.keepSettingsVisible) {
            mFadeHandler.postDelayed({
                fadeOutButtons()
            }, FADE_DELAY)
        }
    }

    private fun fadeOutButtons() {
        fadeAnim(settings.value, .5f)
        fadeAnim(toggle_photo_video.value, .0f)
        fadeAnim(change_resolution.value, .0f)
        fadeAnim(last_photo_video_preview.value, .0f)
    }

    private fun fadeInButtons() {
        fadeAnim(settings.value, 1f)
        fadeAnim(toggle_photo_video.value, 1f)
        fadeAnim(change_resolution.value, 1f)
        fadeAnim(last_photo_video_preview.value, 1f)
        scheduleFadeOut()
    }

    private fun fadeAnim(view: View, value: Float) {
        view.animate().alpha(value).start()
        view.isClickable = value != .0f
    }

    private fun hideNavigationBarIcons() {
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE
    }

    private fun showTimer() {
        video_rec_curr_timer.value.beVisible()
        setupTimer()
    }

    private fun hideTimer() {
        video_rec_curr_timer.value.text = 0.getFormattedDuration()
        video_rec_curr_timer.value.beGone()
        mTimerHandler.removeCallbacksAndMessages(null)
    }

    private fun setupTimer() {
        runOnUiThread(object : Runnable {
            private var mCurrVideoRecTimer = 0
            override fun run() {
                video_rec_curr_timer.value.text = mCurrVideoRecTimer++.getFormattedDuration()
                mTimerHandler.postDelayed(this, 1000L)
            }
        })
    }

    private fun resumeCameraItems() {
        showToggleCameraIfNeeded()
        hideNavigationBarIcons()

        if (!mIsInPhotoMode) {
            initVideoButtons()
        }
    }

    private fun showToggleCameraIfNeeded() {
        toggle_camera.value.beInvisibleIf(countOfCameras() ?: 1 <= 1)
    }

    private fun hasStorageAndCameraPermissions() =
        hasPermission(PERMISSION_WRITE_STORAGE) && hasPermission(PERMISSION_CAMERA)

    private fun setupOrientationEventListener() {
        mOrientationEventListener =
            object : OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
                override fun onOrientationChanged(orientation: Int) {
                    if (isDestroyed) {
                        mOrientationEventListener.disable()
                        return
                    }

                    val currOrient = when (orientation) {
                        in 75..134 -> ORIENT_LANDSCAPE_RIGHT
                        in 225..289 -> ORIENT_LANDSCAPE_LEFT
                        else -> ORIENT_PORTRAIT
                    }

                    if (currOrient != mLastHandledOrientation) {
                        val degrees = when (currOrient) {
                            ORIENT_LANDSCAPE_LEFT -> 90
                            ORIENT_LANDSCAPE_RIGHT -> -90
                            else -> 0
                        }

                        animateViews(degrees)
                        mLastHandledOrientation = currOrient
                    }
                }
            }
    }

    private fun animateViews(degrees: Int) {
        val views = arrayOf<View>(
            toggle_camera.value,
            toggle_flash.value,
            toggle_photo_video.value,
            change_resolution.value,
            shutter.value,
            settings.value,
            last_photo_video_preview.value
        )
        for (view in views) {
            rotate(view, degrees)
        }
    }

    private fun rotate(view: View, degrees: Int) =
        view.animate().rotation(degrees.toFloat()).start()

    private fun checkCameraAvailable(): Boolean {
        if (!mIsCameraAvailable) {
            toast(R.string.camera_unavailable)
        }
        return mIsCameraAvailable
    }

    fun setFlashAvailable(available: Boolean) {
        if (available) {
            toggle_flash.value.beVisible()
        } else {
            toggle_flash.value.beInvisible()
            toggle_flash.value.setImageResource(R.drawable.ic_flash_off_vector)
            mPreview?.setFlashlightState(FLASH_OFF)
        }
    }

    fun setIsCameraAvailable(available: Boolean) {
        mIsCameraAvailable = available
    }

    fun setRecordingState(isRecording: Boolean) {
        runOnUiThread {
            if (isRecording) {
                shutter.value.setImageResource(R.drawable.ic_video_rec)
                toggle_camera.value.beInvisible()
                showTimer()
            } else {
                shutter.value.setImageResource(R.drawable.ic_video_stop)
                showToggleCameraIfNeeded()
                hideTimer()
            }
        }
    }

    fun drawFocusCircle(x: Float, y: Float) = focus_view.value.drawFocusCircle(x, y)

    // 保存回调
    fun mediaSaved(uri: Uri, isPhoto: Boolean) {
        mPreviewUri = uri
        if (isCreateSingle()) {
            finish()
        } else {
            setupPreviewImage()
        }
    }

    override fun finish() {
        if (mPreviewUri != null) {
            Intent().apply {
                data = mPreviewUri
                flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                setResult(Activity.RESULT_OK, this)
            }
        }
        super.finish()
    }

    // 预览大小
    fun setAspectRatio(width: Int, height: Int) {
        runOnUiThread {
            auto_texture_view.value.setAspectRatio(width, height)
            KitCore.release()
        }
    }

    // 人脸回调
    fun onPreviewFrame(
        data: ByteArray?,
        width: Int,
        height: Int,
        sensorOrientation: Int,
        isFrontCamera: Boolean
    ) {
        if (isProcessingFrame || isDestroyed) {
            return
        }
        isProcessingFrame = true
        if (!KitCore.getInit()) {
            Log.e("CameraActivity ", " KitCore Init 1 ")
            if (sensorEventUtil == null) {
                sensorEventUtil = SensorEventUtil(this)
            }
            mFaceTypeByRect = isFaceTypeByRect()
            mFaceTypeByLandmark2d = isFaceTypeByLandmark2d()
            KitCore.init(
                this@CameraActivity.applicationContext,
                AndroidConfig
                    .create()
                    .setCameraMode().also {
                        if (mFaceTypeByRect) {
                            it.openFunc(AndroidConfig.Func.Detect)
                        }
                        if (mFaceTypeByLandmark2d) {
                            it.openFunc(AndroidConfig.Func.Landmark)
                        }
                    }
                    .setDefaultInputImageFormat()
                    .setInputImageSize(width, height)
                    .setOutputImageSize(auto_texture_view.value.width, auto_texture_view.value.height)
            )
            EncoderBus.GetInstance()
                .onSetFrameConfiguration(auto_texture_view.value.height, auto_texture_view.value.width)
            facing_overlay.value.addCallback(object : FaceView.DrawCallback {
                override fun drawCallback(canvas: Canvas?) {
                    EncoderBus.GetInstance().onDraw(canvas)
                }
            })
        }
        // 获取前置后置旋转角度,已经有了 可以传进来
        workHandler?.post {
            data?.also {
                if (sensorEventUtil != null) {
                    var degrees = 0
                    when (sensorEventUtil!!.orientation) {
                        0 -> degrees = 0
                        1 -> degrees = 90
                        2 -> degrees = 270
                        3 -> degrees = 180
                    }

                    var result: Int

                    if (isFrontCamera) {
                        result = (sensorOrientation + degrees) % 360
                        result = (360 - result) % 360
                    } else {
                        result = (sensorOrientation - degrees + 360) % 360
                    }
                    /**
                     * 设置旋转角
                     */
                    KitCore.Camera.setRotation(
                        result - 90,
                        false,
                        auto_texture_view.value.width,
                        auto_texture_view.value.height
                    )
                    /**
                     * 获取人脸信息
                     */
                    val faceDetect = Face.detect(it)
                    if (faceDetect.faceCount > 0) {
                        if (mFaceTypeByRect && mFaceTypeByLandmark2d) {
                            val detectInfos = faceDetect.detectInfos
                            val landmark2d = faceDetect.landmark2d()
                            if (detectInfos != null && detectInfos.size > 0) {
                                val face_rect = arrayOfNulls<Rect>(detectInfos.size)
                                val face_landmarks: MutableList<List<TenginekitPoint>> = ArrayList()
                                for (i in detectInfos.indices) {
                                    face_rect[i] = detectInfos[i].asRect()
                                    face_landmarks.add(landmark2d[i].landmarks)
                                }
                                EncoderBus.GetInstance().onProcessResults(face_rect)
                                EncoderBus.GetInstance().onProcessResults(face_landmarks)
                            }
                        } else if (mFaceTypeByRect) {
                            val detectInfos = faceDetect.detectInfos
                            if (detectInfos != null && detectInfos.size > 0) {
                                val face_rect = arrayOfNulls<Rect>(detectInfos.size)
                                for (i in detectInfos.indices) {
                                    face_rect[i] = detectInfos[i].asRect()
                                }
                                EncoderBus.GetInstance().onProcessResults(face_rect)
                            }
                        }
                        if (isAutoCaptureImage() && !isFaceShow) {
                            isFaceShow = true
                            autoCaptureHandler.postDelayed(
                                autoCaptureImage,
                                isAutoCaptureImageWithTime() * 1000L
                            )
                        }
                    } else {
                        EncoderBus.GetInstance().onProcessResults(null)
                        if (isAutoCaptureImage() && isFaceShow) {
                            isFaceShow = false
                            autoCaptureHandler.removeCallbacks(autoCaptureImage)
                        }
                    }
                }
            }
            if (facing_overlay.value != null) {
                facing_overlay.value.postInvalidate()
            }
            isProcessingFrame = false
        }
    }

    // 按钮的拦截
    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        return if (keyCode == KeyEvent.KEYCODE_CAMERA && !mIsHardwareShutterHandled) {
            mIsHardwareShutterHandled = true
            shutterPressed()
            true
        } else if (!mIsHardwareShutterHandled && appConfig.volumeButtonsAsShutter && (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
            mIsHardwareShutterHandled = true
            shutterPressed()
            true
        } else {
            super.onKeyDown(keyCode, event)
        }
    }

    override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
            mIsHardwareShutterHandled = false
        }
        return super.onKeyUp(keyCode, event)
    }

    // Intent解析
    private fun isImageCaptureIntent() = intent?.action == ACTION_IMAGE

    private fun isVideoCaptureIntent() = intent?.action == ACTION_VIDEO

    private fun isCreateSingle() = intent?.getBooleanExtra(STATE_SINGLE, false) ?: false

    private fun isAutoCaptureImage() = intent?.getBooleanExtra(AUTO_IMAGE_CAPTURE, false) ?: false

    private fun isAutoCaptureImageByFace() = intent?.getBooleanExtra(AUTO_IMAGE_FACE, false)
        ?: false

    private var mFaceTypeByRect: Boolean = false

    private fun isFaceTypeByRect() = intent?.getBooleanExtra(TYPE_FACE_RECT, true) ?: true

    private var mFaceTypeByLandmark2d: Boolean = false

    private fun isFaceTypeByLandmark2d() = intent?.getBooleanExtra(TYPE_FACE_LANDMARK_2D, false)
        ?: false

    private fun isAutoCaptureImageWithTime() = intent?.getIntExtra(AUTO_IMAGE_TIME, -1) ?: -1

    // 权限申请
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        permissio.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

}
